package com.own.component.store.local.method;

import com.own.component.store.core.method.StoreValue;
import com.own.component.store.core.property.LocalStoreProperty;
import com.own.component.store.local.method.scheduler.StoreValueScheduler;
import com.own.component.store.local.method.state.StoreState;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * DefaultLocalStoreValue
 *
 * @author chenxueli
 * @date 2022-06-15 03:14:15
 */
@Slf4j
public class DefaultLocalStoreValue<T> extends DefaultBaseStoreMethod<T> implements StoreValue<T> {

    private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock(true);
    private final Lock writeLock = cacheLock.writeLock();
    private final Lock readLock = cacheLock.readLock();

    public DefaultLocalStoreValue() {
        super(new StoreState<>());
    }

    public DefaultLocalStoreValue(long delay) {
        super(new StoreState<>(), StoreValueScheduler.INSTANCE, delay);
    }

    public DefaultLocalStoreValue(LocalStoreProperty properties) {
        super(new StoreState<>(), StoreValueScheduler.INSTANCE, properties);
    }

    /**
     * 获取所有的key
     *
     * @return 所有的key
     */
    @Override
    public Set<String> keySet() {
        readLock.lock();
        try {
            return getStoreState().keySet();
        } finally {
            readLock.unlock();
        }
    }

    /**
     * 设置缓存
     *
     * @param key   缓存KEY
     * @param value 缓存内容
     */
    @Override
    public void set(String key, T value) {
        writeLock.lock();
        try {
            getStoreState().set(buildKey(key), value);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 设置缓存，指定过期时间
     *
     * @param name     缓存KEY
     * @param value    缓存内容
     * @param duration 指定缓存过期时间
     */
    @Override
    public void set(String name, T value, Duration duration) {
        writeLock.lock();
        try {
            getStoreState().set(buildKey(name), value, duration);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 获取缓存
     *
     * @param key 缓存KEY
     * @return 缓存内容
     */
    @Override
    public T get(String key) {
        readLock.lock();
        try {
            return getStoreState().get(buildKey(key));
        } finally {
            readLock.unlock();
        }
    }

}
